package net.gazhi.delonix.core.validation;

import org.springframework.beans.PropertyAccessException;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.DefaultBindingErrorProcessor;
import org.springframework.validation.FieldError;

/**
 * 改写原有 BindingErrorProcessor 生成的 FieldError，把 value 暴露为 第 {0} 个 message
 * 参数，供国际化输出调用
 * 
 * @author Jeffrey Lin
 *
 */
public class ExposeValueToArgsBindingErrorProcessor extends DefaultBindingErrorProcessor {

	@Override
	public void processPropertyAccessException(PropertyAccessException ex, BindingResult bindingResult) {
		// Create field error with the exceptions's code, e.g. "typeMismatch".
		String field = ex.getPropertyName();
		String[] codes = bindingResult.resolveMessageCodes(ex.getErrorCode(), field);
		Object[] errorArgs = getArgumentsForBindError(bindingResult.getObjectName(), field);
		Object rejectedValue = ex.getValue();
		if (rejectedValue != null && rejectedValue.getClass().isArray()) {
			rejectedValue = StringUtils.arrayToCommaDelimitedString(ObjectUtils.toObjectArray(rejectedValue));
		}

		// { 改写开始 By Jeffrey Lin
		Object[] revisedArgs = new Object[errorArgs.length + 1];
		revisedArgs[0] = rejectedValue;
		for (int i = 0; i < errorArgs.length; i++) {
			revisedArgs[i + 1] = errorArgs[i];
		}
		// 改写结束 }

		bindingResult.addError(new FieldError(bindingResult.getObjectName(), field, rejectedValue, true, codes, revisedArgs, ex.getLocalizedMessage()));
	}

}
